package com.yangtao.springbootfreemarker.web.shiro;

import com.yangtao.core.shiro.PrincipalUser;
import com.yangtao.core.shiro.util.ShiroUtils;
import com.yangtao.core.utils.StringUtil;
import com.yangtao.springbootfreemarker.domain.sys.entity.SysMenu;
import com.yangtao.springbootfreemarker.domain.sys.entity.SysUser;
import com.yangtao.springbootfreemarker.domain.sys.service.SysMenuService;
import com.yangtao.springbootfreemarker.domain.sys.service.SysUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

public class ShiroRealm extends AuthorizingRealm {

	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private SysMenuService sysMenuService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		PrincipalUser principalUser = ShiroUtils.getPrincipalUser(principals);
		// 验证当前用户是否为超级管理员
		List<String> permsList = null;
		if(StringUtil.equals(principalUser.getUsername(), "admin") && StringUtil.equals(principalUser.getOrgId(), "001")) { // 当前用户为超级管理员
			List<SysMenu> menuList = sysMenuService.findAll();
			permsList = new ArrayList<>(menuList.size());
			for (SysMenu sysMenu : menuList) {
				permsList.add(sysMenu.getPerms());
			}
		}else { // 获取当前用户的所有权限
			permsList = sysUserService.queryAllPerms(principalUser.getUserId());
		}
		// 获取数据库权限
		Set<String> permsSet = new HashSet<String>();
		for (String perms : permsList) {
			if (StringUtil.isEmpty(perms)) {
				continue;
			}
			permsSet.addAll(Arrays.asList(perms.trim().split(",")));
		}
		authorizationInfo.addStringPermissions(permsSet);
		return authorizationInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		SysUser sysUser = sysUserService.findOne("username", token.getUsername());
		if(sysUser == null) {
			throw new UnknownAccountException();
		}
		if(StringUtil.equals(sysUser.getStatus(), SysUser.Status.DISABLE.getValue())) {
			throw new DisabledAccountException();
		}
		PrincipalUser data = ShiroUtils.toPrincipalUser(sysUser);
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(data, sysUser.getPassword(), ByteSource.Util.bytes(ShiroUtils.buildHashSource(sysUser.getUsername(), sysUser.getSalt())), getName());
		return info;
	}
}
